﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security;
using System.Windows.Forms;
using Ue.Utility;

namespace Ue.Components.Snap
{
    /// <summary>
    /// 包装后的抓图基类。WebBrowser自带的BrawToBitmap不能抓到一些网站的图片，
    /// 对于一些转向的网站会返回空白图片，所以采用原生的通过IViewObject接口
    /// 取浏览器的图象，实现SNAP。
    /// </summary>
    internal class WebPreview
    {
        private Uri crawlUri = new Uri("about:blank");      //原始uri
        private int thumbImageWeight = 1024;                //期望的缩略图高度
        private int thumbImageHeight = 768;                 //期望的缩略图宽度
        private bool isFullPage = false;                    //是否抓取全图

        public WebPreview(Uri uri, int thumbImageWeight, int thumbImageHeight, bool isFullPage)
        {
            this.thumbImageWeight = thumbImageWeight;
            this.thumbImageHeight = thumbImageHeight;
            this.crawlUri = uri;
            this.isFullPage = isFullPage;
        }

        /// <summary>
        /// 获取Web预览图
        /// </summary>
        /// <returns>Bitmap</returns>
        public Bitmap GetWebPreview()
        {
            var browser = this.BuildBrowser(this.crawlUri);

            try
            {
                //构造snapshot类，抓取浏览器ActiveX的图象
                var snap = new Snapshot();
                var thumBitmap = snap.TakeSnapshot(browser.ActiveXInstance, new Rectangle(0, 0, browser.Width, browser.Height));
                //调整图片大小，这里选择以宽度为标准，高度保持比例
                thumBitmap = (Bitmap)ImageHelper.ResizeImageToAFixedSize(thumBitmap, this.thumbImageWeight, this.thumbImageHeight, ImageHelper.ScaleMode.Width);
                return thumBitmap;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                browser.Dispose();
            }
        }

        #region BuildBrowser

        private WebBrowser BuildBrowser(Uri uri)
        {
            var browser = new WebBrowser()
            {
                ScriptErrorsSuppressed = false,
                ScrollBarsEnabled = false,
                Size = new Size(1024, 768) //浏览器分辨率为1024x768
            };

            browser.NewWindow += new CancelEventHandler(CancelEventHandler);
            browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(DocCompletedEventHandler);

            try
            {
                browser.Navigate(uri);

                //因为没有窗体，所以必须如此
                while (browser.ReadyState != WebBrowserReadyState.Complete)
                {
                    //立即重绘
                    Application.DoEvents();
                }

                //这句最好注释，不然网页上的动画都抓不到了
                browser.Stop();

                if (browser.ActiveXInstance == null)
                {
                    throw new Exception("实例不能为空");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return browser;
        }

        //防止弹窗
        private void CancelEventHandler(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
        }
        //如果是全屏模式，则缩略图调整为网页实际高度和宽度
        private void DocCompletedEventHandler(object sender, EventArgs e)
        {
            var webBrowser = sender as WebBrowser;
            if (webBrowser == null)
            {
                return;
            }

            var imageWidth = webBrowser.Width;
            var imageHeight = webBrowser.Height;
            var size = webBrowser.Size;

            if (this.isFullPage)
            {
                imageHeight = webBrowser.Document.Body.ScrollRectangle.Height;
                imageWidth = webBrowser.Document.Body.ScrollRectangle.Width;
            }
            // 最小宽度不能小于缩略图宽度
            if (imageWidth < this.thumbImageWeight)
                imageWidth = this.thumbImageWeight;

            // 调整最小高度，充满浏览器
            if (imageHeight < size.Height)
                imageHeight = size.Height;

            webBrowser.Size = new Size(imageWidth, imageHeight);
        }

        #endregion
    }
}
